package cn.edu.seu.ssny.controller.admin.system;

import cn.edu.seu.ssny.common.JsonResult;
import cn.edu.seu.ssny.controller.BaseController;
import cn.edu.seu.ssny.entity.*;
import cn.edu.seu.ssny.service.IProjectService;
import cn.edu.seu.ssny.service.IRoleService;
import cn.edu.seu.ssny.service.IUserService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;

import javax.persistence.criteria.*;
import javax.servlet.http.HttpSession;
import java.util.*;

@Controller
@RequestMapping("/admin/user")
public class UserController extends BaseController {
    private final static Logger logger = LoggerFactory.getLogger(UserController.class);

    @Autowired
    private IUserService userService;
    @Autowired
    private IRoleService roleService;
    @Autowired
    private IProjectService projectService;

    private List<Project> getUserProjects(HttpSession session) {
        User currUser = (User) session.getAttribute("currUser");
        Enterprise enterprise = (Enterprise) session.getAttribute("enterprise");
        List<Project> projects;
        if (currUser.getRole().getLevel() != IRoleService.SUPER_LEVEL) {
            projects = currUser.getProjects();
        } else {
            projects = projectService.findAllByEnterprise(enterprise);
        }
        return projects;
    }

    private List<Role> getRoles(HttpSession session) {
        User currUser = (User) session.getAttribute("currUser");
        List<Role> roles;
        if (currUser.getRole().getLevel() != IRoleService.SUPER_LEVEL) {
            roles = roleService.findAllByLevel(0);
        } else {
            roles = roleService.findAll();
        }
        return roles;
    }

    @RequestMapping(value = {"/", "/index"})
    public String index(ModelMap map, HttpSession session) {
        map.put("projects", getUserProjects(session));
        return "admin/user/index";
    }

    @RequestMapping(value = {"/list"})
    @ResponseBody
    public Page<User> list(ModelMap map, HttpSession session) {

        Specification<User> specification = new Specification<User>() {
            @Override
            public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                List<Predicate> predicatesList = new ArrayList<>();
                //首先限制企业
                Enterprise enterprise = (Enterprise) session.getAttribute("enterprise");
                predicatesList.add(cb.equal(root.get("enterprise"), enterprise));

                String usernameSearch = request.getParameter("usernameSearch");
                if (StringUtils.isNotBlank(usernameSearch)) {
                    predicatesList.add(cb.like(root.get("userName"), "%" + usernameSearch + "%"));
                }


                User currUser = (User) session.getAttribute("currUser");
//				if(currUser.getRole().getLevel() != IRoleService.SUPER_LEVEL){
//					//非超级管理员只能查看level普通用户级别的用户
//					Join<User, Role> joinRole = root.join("role",JoinType.INNER);
//					predicatesList.add(cb.lessThan(joinRole.get("level"), 2));
//				}
                Join<User, Role> joinRole = root.join("role", JoinType.INNER);
                predicatesList.add(cb.lessThanOrEqualTo(joinRole.get("level"), currUser.getRole().getLevel()));

                List<Project> projects = new ArrayList<>();
                String projectNameSearch = request.getParameter("projectNameSearch");
                if (StringUtils.isNotBlank(projectNameSearch)) {
                    Project project = projectService.find(Integer.parseInt(projectNameSearch));
                    projects.add(project);
                } else if (currUser.getRole().getLevel() != IRoleService.SUPER_LEVEL) {
                    //非管理员只能看到相关项目的用户
                    projects = currUser.getProjects();
                    System.out.println(projects.size());
                }
                System.out.println(projects.size());
                System.out.println(request.getServletPath());
                if (projects.size() > 0) {
                    Join<User, Project> joinProject = root.join("projects", JoinType.INNER);
                    List<Integer> pids = new ArrayList<>();
                    for (Project project : projects)
                        pids.add(project.getId());
                    predicatesList.add(joinProject.get("id").in(pids));
                }
                //去重
                query.groupBy(root.get("id"));

                Predicate[] predicates = new Predicate[predicatesList.size()];
                return cb.and(predicatesList.toArray(predicates));
            }
        };

        Page<User> page = userService.findAll(specification, getPageRequest());
        return page;
    }

    @RequestMapping(value = "/add", method = RequestMethod.GET)
    public String add(ModelMap map, HttpSession session) {
        map.put("roles", getRoles(session));
        return "admin/user/form";
    }

    @RequestMapping(value = "/edit/{id}", method = RequestMethod.GET)
    public String edit(@PathVariable Integer id, ModelMap map, HttpSession session) {
        map.put("roles", getRoles(session));
        User user = userService.find(id);
        map.put("user", user);
        return "admin/user/form";
    }

    @RequestMapping(value = {"/edit"}, method = RequestMethod.POST)
    @ResponseBody
    public JsonResult edit(User user) {
        userService.saveOrUpdate(user);
        return JsonResult.success();
    }

    @RequestMapping(value = "/delete/{id}", method = RequestMethod.POST)
    @ResponseBody
    public JsonResult delete(@PathVariable Integer id, ModelMap map) {
        try {
            userService.delete(id);
        } catch (Exception e) {
            e.printStackTrace();
            return JsonResult.failure(e.getMessage());
        }
        return JsonResult.success();
    }

    @RequestMapping(value = "/deletems/{ids}", method = RequestMethod.POST)
    @ResponseBody
    public JsonResult deletems(@PathVariable String ids, ModelMap map) {
        if (ids == null)
            return JsonResult.failure("删除失败");
        String[] idArray = ids.split("&");
        for (String id : idArray) {
            try {
                userService.delete(Integer.parseInt(id));
            } catch (Exception e) {
                e.printStackTrace();
                return JsonResult.failure(e.getMessage());
            }
        }
        return JsonResult.success();
    }

    @RequestMapping(value = "/grant/{id}", method = RequestMethod.GET)
    public String grant(@PathVariable Integer id, ModelMap map, HttpSession session) {
        User user = userService.find(id);
        map.put("user", user);

        List<Project> list = user.getProjects();
        List<Integer> projectIds = new ArrayList<Integer>();
        for (Project project : list) {
            projectIds.add(project.getId());
        }
        map.put("projectIds", projectIds);

        map.put("projects", getUserProjects(session));

        return "admin/user/grant";
    }

    @ResponseBody
    @RequestMapping(value = "/grant/{id}", method = RequestMethod.POST)
    public JsonResult grant(@PathVariable Integer id, String[] projectIds, ModelMap map) {
        try {
            userService.grant(id, projectIds);
        } catch (Exception e) {
            e.printStackTrace();
            return JsonResult.failure(e.getMessage());
        }
        return JsonResult.success();
    }
}
